<template>
  <div class="scanCode">
    <div class="container">
      <div id="reader"></div>
    </div>
    <div class="tip">
      <p>将二维码/条码放入框内，即可自动扫描</p>
      <van-uploader
        v-model="fileList"
        :preview-image="false"
        :after-read="dealSelectFiles"
      >
        <p class="code">我的二维码</p></van-uploader
      >
    </div>
    <div class="btn">
      <!-- <div class="left-back">
        <van-icon name="arrow-left" @click="clickBack" />
      </div> -->
      <!-- <div class="right-file">
        <van-uploader
          v-model="fileList"
          :preview-image="false"
          :after-read="dealSelectFiles"
        >
          <van-icon name="photo-o"
        /></van-uploader>
      </div> -->
    </div>
  </div>
</template>
​
<script setup>
import { ref, reactive } from 'vue';
import { onMounted, onUnmounted } from 'vue';
import { Html5Qrcode } from 'html5-qrcode';
import { showToast } from 'vant';
// import VConsole from 'vconsole';
// const vConsole = new VConsole({ theme: 'dark' });
// import SanCOde from '@/assets/images/sancode.png';

const emit = defineEmits(['handleSanCode']);
const cameraId = ref();
onMounted(() => {
  getCameras();
});
onUnmounted(() => {
  //扫描设备是否在运行
  // if (state.html5QrCode.isScanning) {
  stop();
  // }
  // 结束调试后，可移除掉
  // vConsole && vConsole.destroy();
});

const state = reactive({
  html5QrCode: null,
  fileList: [],
});
const start = () => {
  state.html5QrCode
    .start(
      // 后置摄像头
      { facingMode: 'environment' },
      // { deviceId: { exact: cameraId.value } },
      {
        fps: 50,
        qrbox: { width: 250, height: 250 },
      },
      (decodedText, decodedResult) => {
        if (decodedText) {
          showToast({
            message: '扫码成功:' + decodedText,
            duration: 800,
          });
          setTimeout(() => {
            emit('handleSanCode', decodedText);
          }, 800);
        } else {
          showToast({
            message: '扫码失败:',
            duration: 800,
          });
        }
      }
    )
    .catch((err) => {
      console.log('扫码错误信息', err);
      let message = ''; // 错误信息处理仅供参考，具体描述自定义
      if (typeof err == 'string') {
        message = '二维码识别失败！';
      } else {
        if (err.name == 'NotAllowedError') {
          message = '您需要授予相机访问权限！';
        }
        if (err.name == 'NotFoundError') {
          message = '这个设备上没有摄像头！';
        }
        if (err.name == 'NotSupportedError') {
          message = '摄像头访问只支持在安全的上下文中，如https或localhost！';
        }
        if (err.name == 'NotReadableError') {
          message = '相机被占用！';
        }
        if (err.name == 'OverconstrainedError') {
          message = '安装摄像头不合适！';
        }
        if (err.name == 'StreamApiNotSupportedError') {
          message = '此浏览器不支持流API！';
        }
      }
      showToast({
        message,
        duration: 3000,
      });
    });
};
const getCameras = () => {
  Html5Qrcode.getCameras()
    .then((devices) => {
      if (devices && devices.length) {
        state.html5QrCode = new Html5Qrcode('reader');
        cameraId.value = devices[1].id;
        start();
      }
    })
    .catch((err) => {
      showToast({
        message: '摄像头无访问权限！',
        duration: 3000,
      });
    });
};
const stop = () => {
  state.html5QrCode &&
    state.html5QrCode
      .stop()
      .then((ignore) => {
        console.log('停止扫码', ignore);
      })
      .catch((err) => {
        console.log(err);
        showToast('停止扫码失败');
      });
};
const dealSelectFiles = () => {
  try {
    window.qrcode.callback = (result) => {
      showToast('成功了，结果是：' + result);
    }; // get select files.
    let file = state.fileList[0].file;
    var reader = new FileReader();
    reader.onload = (function () {
      return function (e) {
        window.qrcode.decode(e.target.result);
      };
    })(file);
    reader.readAsDataURL(file);
  } catch (error) {
    showToast({
      message: '图片识别失败！',
      duration: 3000,
    });
  }
};
</script>

<style lang="scss">
.scanCode {
  height: calc(100vh - 110px);
  display: flex;
  flex-direction: column;
  background-color: #a5a1a1;
  font-weight: 400;
  font-size: 14px;
  color: #ffffff;
  font-family: PingFang SC, PingFang SC;
}
.tip {
  position: relative;
  top: -150px;
  text-align: center;
  opacity: 1;
  line-height: 24px;
}
.code {
  margin-top: 20px;
  display: inline-block;
  opacity: 1;
  width: 120px;
  height: 30px;
  line-height: 30px;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 15px 15px 15px 15px;
}
.container {
  height: 100%;
  position: relative;
  width: 100%;
}

#reader {
  position: relative;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}
#qr-shaded-region {
  background: url('@/assets/images/sancode.png') no-repeat !important;
  background-size: 100% 100% !important;

  div {
    opacity: 0;
  }
}
.btn {
  flex: 1;
  padding: 3vw;
  display: flex;
  justify-content: space-around;
  color: #fff;
  font-size: 8vw;
  align-items: flex-start;
}
</style>
​
